// Captor.h : Defines the exported functions for the DLL application.
//

#ifndef __CAPTOR_H__
#define __CAPTOR_H__

#include "stdafx.h"
#include "ATASHD3D.h"
#include "HookD3D.h"
#include "DeviceHooker.h"

CONST DWORD CAPTURE_SEQUENCY = 10;

class CUnknown : public IUnknown
{
	ULONG m_ulRef;
public:
	CUnknown() : m_ulRef(0)
	{
	}

	STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj)
	{
		if (riid == IID_IUnknown)
		{
			AddRef();
			*ppvObj = this;
			return S_OK;
		}
		return E_NOINTERFACE;
	}

	STDMETHOD_(ULONG,AddRef)(THIS)
	{
//		DebugInfoTempA("add ref: %d", m_ulRef);
		return ++m_ulRef;
	}

	STDMETHOD_(ULONG,Release)(THIS)
	{
//		DebugInfoTempA("release ref: %d", m_ulRef);

		if (!--m_ulRef)
		{
			OnFinal();
			return 0;
		}
		return m_ulRef;
	}
	virtual void OnFinal() = 0;
};

class CCaptorManager;

class CCaptor : public CUnknown
{
	CCaptorManager* m_pmgr;
	char m_szDeviceName[32];
	HANDLE m_hMutex;
	HANDLE m_hFile;
	HANDLE m_hFileMapping;
	FMH_Capture* m_pcap;
	RPB_CreateCaptor m_rpb;
	HRGN m_hrgn;

	IDirect3DSwapChain9* m_pSwapChain;
	CDeviceHookerDrawPrimitive9* m_pDeviceHooker;

	IDXGISwapChainDWM* m_pDXGISwapChain;
	ID3D10Texture2D* m_pTexture;
	ID3D10Device* m_pDevice;

	DWORD m_dwLastCaptureTime;
public:
	static CD3D9HookDrawPrimitive::PROC IDirect3DDevice9DrawPrimitive;
	static CD3D10HookDraw::PROC ID3D10Draw;
	static CD3D10HookDrawIndexed::PROC ID3D10DrawIndexed;

	CCaptor(CCaptorManager* pmgr);
	~CCaptor();

	BOOL Create(LPCSTR szDeviceName);
	void Destroy();
	BOOL ConnectDevice9(IDirect3DSwapChain9* pSwapChain, CDeviceHookerBase* pDeviceHooker);
	void DisconnectDevice();
	void OnFinal();
	BOOL AddDirty(IDirect3DSurface9* pSurface, RECT* prc);
	BOOL Capture();

	BOOL ConnectDevice10(IDXGISwapChainDWM* pDXGISwapChain, ID3D10Device* pDevice);
	BOOL Capture10();
	BOOL AddDirty10(LPRECT prc, LPTSTR pAdd);

	const char* GetDeviceName()
	{
		return m_szDeviceName;
	}

	RPB_CreateCaptor* GetCreateParameter()
	{
		return &m_rpb;
	}

	HANDLE GetMutex()
	{
		return m_hMutex;
	}

	HANDLE GetFileMapping()
	{
		return m_hFileMapping;
	}
};

#endif //__CAPTOR_H__
